﻿/*
 *  Copyright 2009 Coditate Software
 *  Licensed under the GNU Library General Public License (LGPL) 2.1 
 *  
 *  License available at: http://simplesavant.codeplex.com/license
 */
using System;
using System.Collections;
using System.Collections.Generic;

namespace Coditate.Savant.Async
{
    /// <summary>
    /// Tracks the status and completion of multiple <see cref="AsyncAction"/>s.
    /// </summary>
    /// <remarks>
    /// Pass an instance of this class to <see cref="AsyncExtensions.ExecuteAsync(ISimpleSavant, Action{ISimpleSavant}, ref ActionTracker)"/>
    /// to track multiple, asynchronous actions.
    /// </remarks>
    public class ActionTracker
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="ActionTracker"/> class.
        /// </summary>
        public ActionTracker()
        {
            Actions = new List<AsyncAction>();
        }

        /// <summary>
        /// Gets or sets the actions tracked by this instance.
        /// </summary>
        /// <value>The actions.</value>
        public List<AsyncAction> Actions { get; private set; }

        /// <summary>
        /// Gets a value indicating whether all actions have completed or not.
        /// </summary>
        /// <value><c>true</c> if all actions have completed; otherwise, <c>false</c>.</value>
        /// <remarks>This method returns immediately with no blocking.</remarks>
        public bool AreCompleted
        {
            get
            {
                lock (((ICollection) Actions).SyncRoot)
                {
                    foreach (AsyncAction action in Actions)
                    {
                        if (!action.IsCompleted)
                        {
                            return false;
                        }
                    }
                }
                return true;
            }
        }

        /// <summary>
        /// Ends invocations for all actions.
        /// </summary>
        /// <remarks>
        /// This method blocks until all actions have completed successfully or 
        /// throws the first exception encountered by a failed invocation.
        /// </remarks>
        public void EndInvocations()
        {
            lock (((ICollection) Actions).SyncRoot)
            {
                foreach (AsyncAction action in Actions)
                {
                    action.EndInvoke();
                }
            }
        }
    }
}